package com.liusy.serachengine.mail;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.mail.Address;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Part;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;

import org.apache.log4j.Logger;

public class ResolveEml {

   private static Logger log            = Logger.getLogger(ResolveEml.class);
   private MimeMessage   mimeMessage    = null;

   private String        saveAttachPath = "";                                // 附件下载后的存放目录

   private StringBuffer  bodytext       = new StringBuffer();                // 存放邮件内容的StringBuffer对象

   private boolean       bodytextFilled = false;                             //bodytext是否已经填充了（主要是为了避免重复取值）

   private String        dateformat     = "yyyy-MM-dd HH:mm";                // 默认的日期显示格式

   private List          attachments    = new ArrayList();

   private static int    count          = 0;
   

   public ResolveEml() {
   }

   public ResolveEml(MimeMessage mimeMessage) {
      this.mimeMessage = mimeMessage;
   }

   public void setMimeMessage(MimeMessage mimeMessage) {
      this.mimeMessage = mimeMessage;
   }
   

   public String getFrom() throws Exception {
      InternetAddress address[] = (InternetAddress[]) mimeMessage.getFrom();
      String from = address[0].getAddress();
      if (from == null) from = "";
      String personal = address[0].getPersonal();
      if (personal == null) personal = "";
      String fromaddr = personal + "<" + from + ">";
      return fromaddr;
   }

   public String getMailAddress(String type) throws Exception {
      String mailaddr = "";
      String addtype = type.toUpperCase();
      InternetAddress[] address = null;
      if (!addtype.equals("TO") && !addtype.equals("CC") && !addtype.equals("BCC")) throw new Exception("Error emailaddr type!");
      if (addtype.equals("TO")) {
         address = (InternetAddress[]) mimeMessage.getRecipients(Message.RecipientType.TO);
      }
      else if (addtype.equals("CC")) {
         address = (InternetAddress[]) mimeMessage.getRecipients(Message.RecipientType.CC);
      }
      else {
         address = (InternetAddress[]) mimeMessage.getRecipients(Message.RecipientType.BCC);
      }
      if (address != null&&address.length>0) {
         for (int i = 0; i < address.length; i++) {
            String email = address[i].getAddress();
            if (email == null) email = "";
            else {
               email = MimeUtility.decodeText(email);
            }
            String personal = address[i].getPersonal();
            if (personal == null) personal = "";
            else {
               personal = MimeUtility.decodeText(personal);
            }
            String compositeto = personal + "<" + email + ">";
            mailaddr += "," + compositeto;
         }
         mailaddr = mailaddr.substring(1);
      }

      return mailaddr;
   }

   public String getSubject() throws MessagingException {
      String subject = "";
      try {
         subject = MimeUtility.decodeText(mimeMessage.getSubject());
         if (subject == null) subject = "";
      }
      catch (Exception exce) {
      }
      return subject;
   }

   public Date getSentDate() throws Exception {
      Date sentdate = mimeMessage.getSentDate();
      return sentdate;
   }


	 
	 /**
	 　*　【保存附件】 　
	  * @throws Exception 
	  * @throws IOException 
	  * @throws MessagingException 
	  * @throws Exception */
	 public List saveAttachMent(Part part,int currentMaxId,String virtualPath) throws Exception {
	  String fileName="";
	  if(part.isMimeType("multipart/*")){
		  MimeMultipart mp=(MimeMultipart)part.getContent();
		  int attachCount=0;
		  int current=0;
	   for(int j=0;j<mp.getCount();j++){
	    BodyPart mpart=mp.getBodyPart(j);
	    String disposition=mpart.getDisposition();
	    if((disposition!=null)&&disposition.equals(Part.ATTACHMENT)){
	     fileName=MimeUtility.decodeText(mpart.getFileName());
	     current=currentMaxId+attachCount;
	     log.debug("检测到附件: " +fileName);
	     File file=saveFile(fileName,mpart.getInputStream(),current);
	     //将附件信息存储到数据结构中
		   Map attachment = new HashMap();
		   attachment.put("id", current+"");
	       attachment.put("filename", virtualPath+"\\"+current+"_"+fileName);
	       attachment.put("attchname", fileName);
	       attachment.put("attchsize", file.length()+" bytes");
	       attachments.add(attachment);
	       
	       attachCount++;
	    }
	   }
	  }
	  else if(part.isMimeType("message/rfc822")){
	   saveAttachMent((Part)part.getContent(),currentMaxId,virtualPath);
	  }
	  
	  return attachments;
	 }

   public String getBodyText() throws MessagingException, IOException, Exception {
      getMailContent(mimeMessage);
      return bodytext.toString();
   }


   public void getMailContent(Part part) throws Exception {
      String contenttype = part.getContentType();
      int nameindex = contenttype.indexOf("name");
      boolean conname = false;
      if (nameindex != -1) conname = true;

      if (part.isMimeType("text/plain") && !conname && !bodytextFilled) {
         bodytext.append((String) part.getContent());
         bodytextFilled = true;
      }
      else if (part.isMimeType("text/html") && !conname && !bodytextFilled) {
         bodytext.append((String) part.getContent());
         bodytextFilled = true;
      }
      else if (part.isMimeType("multipart/*")) {
         MimeMultipart multipart = (MimeMultipart) part.getContent();
         int counts = multipart.getCount();
         for (int i = counts-1; i >0; i--) {
            getMailContent(multipart.getBodyPart(i));
         }
      }
      else if (part.isMimeType("message/rfc822")) {
         getMailContent((Part) part.getContent());
      }

   }

   public boolean getReplySign() throws MessagingException {
      boolean replysign = false;
      String needreply[] = mimeMessage.getHeader("Disposition-Notification-To");
      if (needreply != null) {
         replysign = true;
      }
      return replysign;
   }

   public String getSender() throws MessagingException, Exception {
      String sender = "";
      Address address = mimeMessage.getSender();
      if (address != null) {
         sender = MimeUtility.decodeText(address.toString());
      }
      return sender;
   }

   public String getMessageId() throws MessagingException {
      return mimeMessage.getMessageID();
   }

   /**
    * 判断此邮件是否包含附件
    * 
    * @throws MessagingException
    */
   public boolean isContainAttach(Part part) throws Exception {
      boolean attachflag = false;
      String contentType = part.getContentType();
      if (part.isMimeType("multipart/*")) {
         MimeMultipart mp = (MimeMultipart) part.getContent();
         //获取附件名称可能包含多个附件
         for (int j = 0; j < mp.getCount(); j++) {
            BodyPart mpart = mp.getBodyPart(j);
            String disposition = mpart.getDisposition();
            if ((disposition != null) && disposition.equals(Part.ATTACHMENT)) {
               attachflag = true;
            }
            else if (mpart.isMimeType("multipart/*")) {
               attachflag = isContainAttach((Part) mpart);
            }
         }
      }
      else if (part.isMimeType("message/rfc822")) {
         attachflag = isContainAttach((Part) part.getContent());
      }
      return attachflag;
   }


   public void setAttachPath(String attachpath) {
      this.saveAttachPath = attachpath;
   }

   public void setDateFormat(String format) throws Exception {
      this.dateformat = format;
   }

   public String getAttachPath() {
      return saveAttachPath;
   }

   private File saveFile(String fileName, InputStream in, int currentMaxId) throws Exception {
      String osName = System.getProperty("os.name");
      String storedir = getAttachPath();
      String separator = "";
      if (osName == null) osName = "";
      if (osName.toLowerCase().indexOf("win") != -1) {
         separator = "\\";
         if (storedir == null || storedir.equals("")) storedir = "c:\\tmp";
      }
      else {
         separator = "/";
         storedir = "/tmp";
      }
      File storefile = new File(storedir + separator + currentMaxId + "_" + fileName);
      // for(int i=0;storefile.exists();i++){
      // storefile = new File(storedir+separator+fileName+i);
      // }
      BufferedOutputStream bos = null;
      BufferedInputStream bis = null;
      try {
         bos = new BufferedOutputStream(new FileOutputStream(storefile));
         bis = new BufferedInputStream(in);
         int c;
         while ((c = bis.read()) != -1) {
            bos.write(c);
            bos.flush();
         }

      }
      catch (Exception exception) {
         exception.printStackTrace();
         throw new Exception("文件保存失败!");
      }
      finally {
         bos.close();
         bis.close();
      }

      return storefile;
   }

   public Map getInfo() throws Exception {
      String fileName = "";
      return null;
   }
  

}
